/*
 * @Author: gggg 1263457581@qq.com
 * @Date: 2025-06-18 11:35:29
 * @LastEditors: gggg 1263457581@qq.com
 * @LastEditTime: 2025-06-18 11:46:21
 * @FilePath: /algorithm-and-data-struct/designmode/Observer_callback.cpp
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */

#include <iostream>
#include <vector>
#include <memory>
#include <functional>
#include <algorithm>

class Subject {
public:
    using Callback = std::function<void(const std::string&)>;

    void attach(std::shared_ptr<Callback> cb) {
        callbacks.push_back(cb);
    }

    void detach(std::shared_ptr<Callback> cb) {
        callbacks.erase(
            std::remove_if(callbacks.begin(), callbacks.end(),
                [&](const std::shared_ptr<Callback>& ptr) {
                    return ptr.get() == cb.get();
                }),
            callbacks.end()
        );
    }

    void notify(const std::string& message) {
        for (auto it = callbacks.begin(); it != callbacks.end();) {
            if (auto cb = it->lock()) {  // 检查是否有效
                (*cb)(message);  // 调用回调
                ++it;
            } else {
                it = callbacks.erase(it);  // 清理失效回调
            }
        }
    }

private:
    std::vector<std::weak_ptr<Callback>> callbacks;
};

int main() {
    auto subject = std::make_shared<Subject>();

    // Lambda 回调
    auto cb1 = std::make_shared<Subject::Callback>([](const std::string& msg) {
        std::cout << "[Lambda] Received: " << msg << std::endl;
    });

    // 函数指针
    void freeFunction(const std::string& msg) {
        std::cout << "[Free Function] Received: " << msg << std::endl;
    }
    auto cb2 = std::make_shared<Subject::Callback>(freeFunction);

    // 成员函数绑定
    class MyClass {
    public:
        void memberFunction(const std::string& msg) {
            std::cout << "[Member Function] Received: " << msg << std::endl;
        }
    };
    MyClass obj;
    auto cb3 = std::make_shared<Subject::Callback>(
        std::bind(&MyClass::memberFunction, &obj, std::placeholders::_1)
    );

    // 注册回调
    subject->attach(cb1);
    subject->attach(cb2);
    subject->attach(cb3);

    // 通知所有回调
    subject->notify("Hello Observers!");

    // 移除其中一个回调
    subject->detach(cb1);

    // 再次通知
    subject->notify("Observers after removal.");
}